package com.xzj.admin.analysis.base.custom.it;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xzj.admin.analysis.base.common.handle.CommonAbstractAnalysisHandle;
import com.xzj.admin.analysis.base.constants.CommonEnums;
import com.xzj.admin.analysis.base.custom.common.CommonAnalysis;
import com.xzj.admin.analysis.base.util.AnalysisCommonUtil;
import com.xzj.admin.analysis.base.util.XmlToJsonUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: xzj-admin
 * @ClassName: ItCasAnalysisHandle
 * @description: IT云CAS
 * @author: XiaZunJun
 * @create: 2024-11-11 15:48
 */
@Slf4j
public class CasAnalysisHandle extends CommonAbstractAnalysisHandle {

    private static final Map<String, Map<String, String>> CLUSTER_HOST_STAT_MAP = new ConcurrentHashMap<>();

    static {
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.region.name(), CommonAnalysis::regionSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.host.name(), CasAnalysisHandle::hostSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.storage.name(), CasAnalysisHandle::storageSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.vSwitch.name(), CasAnalysisHandle::vSwitchSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.vm.name(), CasAnalysisHandle::vmSub);
        Map<String, String> clusterStatMap = new HashMap<>();
        clusterStatMap.put("CPU总核数", "cpuCoresTotal");
        clusterStatMap.put("已分配CPU", "cpuCoresAssigned");
        clusterStatMap.put("总内存", "memorySizeTotal");
        clusterStatMap.put("已分配内存", "memorySizeAssigned");
        clusterStatMap.put("共享存储容量", "shareStorageTotal");
        clusterStatMap.put("已分配共享存储", "shareStorageAssigned");
        clusterStatMap.put("本地总存储", "localStorageTotal");
        clusterStatMap.put("本地总可用存储", "localStorageAvailable");
        CLUSTER_HOST_STAT_MAP.put(CommonEnums.RESOURCE_TYPE.cluster.name(), clusterStatMap);
        Map<String, String> hostStatMap = new HashMap<>();
        hostStatMap.put("系统运行时间", "runTime");
        CLUSTER_HOST_STAT_MAP.put(CommonEnums.RESOURCE_TYPE.host.name(), hostStatMap);
        Map<String, String> datacenterStatMap = new HashMap<>();
        datacenterStatMap.put("本地总存储", "localStorageTotal");
        datacenterStatMap.put("本地总可用存储", "localStorageAvailable");
        CLUSTER_HOST_STAT_MAP.put(CommonEnums.RESOURCE_TYPE.datacenter.name(), datacenterStatMap);
    }

    public CasAnalysisHandle(String cloudId,String cloudType) {
        super(cloudId, cloudType,new CasThemeSpecialAnalysisHandle(cloudId,cloudType));
    }

    @Override
    public void analysisBefore(JSONObject msgJson) {
        String theme = null;
        // 1. xml转json
        for (String key : msgJson.keySet()) {
            if (CommonEnums.RESOURCE_TYPE.region.equals(key) || CommonEnums.RESOURCE_TYPE.pushEnd.equals(key)) {
                return;
            }
            if (CommonEnums.RESOURCE_TYPE.datacenter.equals(key)) {
                theme = key;
                JSONObject datacenterJson = msgJson.getJSONObject(key);
                String extInfoXml = datacenterJson.getString("extInfo");
                JSONObject extInfoJson = XmlToJsonUtil.startXMLToJSON(extInfoXml);
                datacenterJson.put("extInfo", extInfoJson);
                msgJson.put(key, datacenterJson);
                break;
            }
            if (CommonEnums.JSON_FIELD.EXTEND.judgeEquals(key)) {
                theme = key;
                String xml = msgJson.getString(key);
                if (xml.startsWith("{")) {
                    JSONObject xmlJson = msgJson.getJSONObject(key);
                    for (String xmlKey : xmlJson.keySet()) {
                        String subXml = xmlJson.getString(xmlKey);
                        if (subXml.startsWith("<")) {
                            JSONObject x = XmlToJsonUtil.startXMLToJSON(subXml);
                            xmlJson.put(xmlKey, x);
                        }
                    }
                    msgJson.put(key, xmlJson);
                } else {
                    JSONObject x = XmlToJsonUtil.startXMLToJSON(msgJson.getString(key));
                    msgJson.put(key, x);
                }
                break;
            }
        }
        // 2. 个别资源特殊处理
        specialResourceBefore(msgJson, theme);
    }

    /**
     * 个别资源特殊处理
     *
     * @param msgJson 原始json
     * @param theme   对应需要处理的主题
     * @author xiazunjun
     * @date 2024/1/9 17:58
     */
    private void specialResourceBefore(JSONObject msgJson, String theme) {
        // 需要处理统计数据的主题
        if (CLUSTER_HOST_STAT_MAP.containsKey(theme)) {
            Map<String, String> statMap = CLUSTER_HOST_STAT_MAP.get(theme);
            JSONObject themeJson = msgJson.getJSONObject(theme);
            JSONArray stats;
            if (CommonEnums.RESOURCE_TYPE.datacenter.equals(theme)) {
                stats = themeJson.getJSONObject("extInfo").getJSONArray("keyValue");
                for (int i = 0; i < stats.size(); i++) {
                    JSONObject stat = stats.getJSONObject(i);
                    if (statMap.containsKey(stat.getString("key"))) {
                        themeJson.put(statMap.get(stat.getString("key")), stat.getString("value"));
                    }
                }
            } else {
                stats = themeJson.getJSONObject("stat").getJSONArray("keyValue");
                JSONObject detail = themeJson.getJSONObject("detail");
                for (int i = 0; i < stats.size(); i++) {
                    JSONObject stat = stats.getJSONObject(i);
                    if (statMap.containsKey(stat.getString("key"))) {
                        detail.put(statMap.get(stat.getString("key")), stat.getString("value"));
                    }
                }
                if (CommonEnums.RESOURCE_TYPE.cluster.equals(theme)) {
                    String datacenterId =
                            msgJson.getJSONObject(CommonEnums.JSON_FIELD.EXTEND.getValue()).getString("datacenterId");
                    detail.put("datacenterId", datacenterId);
                }
                themeJson.put("detail", detail);
            }
            msgJson.put(theme, themeJson);
        } else if (CommonEnums.RESOURCE_TYPE.network.equals(theme)) {
            JSONObject themeJson = msgJson.getJSONObject(theme);
            String vmId = msgJson.getJSONObject(CommonEnums.JSON_FIELD.EXTEND.getValue()).getString("vmId");
            Object networkObj = themeJson.get("network");
            if (networkObj instanceof JSONArray) {
                JSONArray networks = themeJson.getJSONArray("network");
                for (int i = 0; i < networks.size(); i++) {
                    JSONObject network = networks.getJSONObject(i);
                    network.put("vmId", vmId);
                }
                themeJson.put("network", networks);
            } else {
                JSONObject network = themeJson.getJSONObject("network");
                network.put("vmId", vmId);
                themeJson.put("network", network);
            }
            msgJson.put(theme, themeJson);
        }
    }

    /**
     * 构建依托于主机 主机与集群关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    private static void hostSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        // summary:clusterId
        String[] fields = fieldName.split(CommonEnums.JOIN.DEFAULT.getValue());
        JSONObject summaryJson = row.getJSONObject(fields[0]);
        String clusterId = summaryJson.getString(fields[1]);
        JSONObject subJson = new JSONObject();
        subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, clusterId));
        subJson.put("hostId", parentId);
        subJson.put("clusterId", clusterId);
        subThemeRows.add(subJson);
    }

    /**
     * 构建依托于虚机 虚机硬件扩展信息
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    private static void vmSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        JSONArray subArrays = row.getJSONArray(fieldName);
        for (int i = 0; i < subArrays.size(); i++) {
            JSONObject subJson = subArrays.getJSONObject(i);
            subJson.put("vmId", parentId);
            // 显卡
            if ("graphics".equals(fieldName)) {
                subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, subJson.getString("port")));
                subJson.put("hardwareType", "VirtualMachineVideoCard");
            } else {
                String deviceName = subJson.getString("deviceName");
                String targetBus = subJson.getString("targetBus");
                subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, targetBus, deviceName));
                subJson.put("hardwareType", "vm-storage");
            }
            subThemeRows.add(subJson);
        }
    }

    /**
     * 构建依托于虚拟交换机 虚拟交换机和主机关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    private static void vSwitchSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        // hostId
        String hostId = row.getString(fieldName);
        if (StrUtil.isNotEmpty(hostId)) {
            JSONObject subJson = new JSONObject();
            subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, hostId));
            subJson.put("hostId", hostId);
            subJson.put("specId", "12960001");
            subJson.put("vSwitchId", parentId);
            subThemeRows.add(subJson);
        }
    }

    /**
     * 构建依托于虚拟存储 虚拟存储与集群关系、虚拟存储与主机关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    private static void storageSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        String id = row.getString(fieldName);
        JSONObject subJson = new JSONObject();
        subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, id));
        if ("clusterId".equals(fieldName)) {
            // 虚拟存储与集群关系
            subJson.put("specId", "12580004");
            subJson.put("clusterId", id);
        } else {
            // 虚拟存储与主机关系
            subJson.put("specId", "12580002");
            subJson.put("hostId", id);
        }
        subJson.put("storageId", parentId);
        subThemeRows.add(subJson);
    }
}
